home *** CD-ROM | disk | FTP | other *** search
- /*
- Commodore 64 Emulator v0.4 Earle F. Philhower III
- Copyright (C) 1993-4 (st916w9r@dunx1.ocs.drexel.edu)
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
- #include "Processor.h"
- #include "Traps.h"
- #include "Serial.h"
- #include "Error.h"
-
- typedef struct
- {
- byte inuse : 1;
- byte isopen : 1;
- byte (*getf)(byte *, int);
- byte (*putf)(byte, int);
- byte (*openf)(char *, int, int);
- byte (*closef)(int);
- void (*flushf)(int);
- } SerialType;
- static SerialType device[16];
-
- #define BUFFERLEN 127
- static byte serialBuffer[BUFFERLEN];
-
- static byte serialPtr, latestListen, trapListen, latestSaListen;
-
- static void SerialSendByte(void), SerialRecieveByte(void), SerialListen(void),
- SerialSaListen(void), FloppyReadyTrap(void);
- static byte SerialDummy(void);
-
- static trap serialTrap[] =
- {
- { 0xed40, {0x78, 0x20, 0x97}, SerialSendByte },
- { 0xee13, {0x78, 0xa9, 0x00}, SerialRecieveByte },
- { 0xed0e, {0x20, 0xa4, 0xf0}, SerialListen },
- { 0xed36, {0x78, 0x20, 0x8e}, SerialSaListen },
- { 0xeea9, {0xad, 0x00, 0xdd}, FloppyReadyTrap }
- };
-
- int SerialInitialize(void)
- {
- byte i;
- SerialType *p;
-
- AddTrap(serialTrap[0]);
- AddTrap(serialTrap[1]);
- AddTrap(serialTrap[2]);
- AddTrap(serialTrap[3]);
- AddTrap(serialTrap[4]);
-
- for (i = 0; i < 16; i++) {
- p=&device[i];
- p->getf=(byte (*)(byte *, int ))SerialDummy;
- p->putf=(byte (*)(byte, int ))SerialDummy;
- p->openf=(byte (*)(char *, int , int ))SerialDummy;
- p->closef=(byte (*)(int ))SerialDummy;
- p->flushf=(void (*)(int ))NULL; }
-
- return kNoError;
- }
-
- void AddSerialDevice(int devnum, byte (*getf)(byte *, int),
- byte (*putf)(byte, int), byte (*openf)(char *, int, int),
- byte (*closef)(int), void (*flushf)(int))
- {
- SerialType *p;
-
- if ((devnum<0)||(devnum>15)) InternalError(kInvalidDeviceNumber);
- p=&device[devnum];
- if (p->inuse!=0) InternalError(kDeviceNumberInUse);
-
- p->getf = getf;
- p->putf = putf;
- p->openf = openf;
- p->closef = closef;
- p->flushf = flushf;
- p->inuse = 1;
- }
-
-
- static void SerialSendByte(void)
- {
- byte data;
- SerialType *p;
- extern void i60(void);
-
- data=RAM[0x95];
- p=&device[latestListen&0x0f];
-
- if (p->isopen==0) {
- if (serialPtr<BUFFERLEN) serialBuffer[serialPtr++] = data; }
- else (*p->putf)(data, latestSaListen & 0x0f);
- i60(); /* RTS */
- }
-
- static void SerialRecieveByte(void)
- {
- byte pp;
- SerialType *p;
- extern void i60(void);
-
- p=&device[latestListen&0x0f];
-
- RAM[0x90]=(*p->getf)(&pp, latestSaListen&0x0f);
- RAM[0xa4]=a=pp;
- flags &= ~CAR;
- i60(); /* RTS */
- }
-
- static void SerialListen(void)
- {
- extern void i60(void);
-
- trapListen=a;
- i60(); /* RTS */
- }
-
- static void SerialSaListen(void)
- {
- SerialType *p;
- byte b, i;
- extern void i60(void);
-
- b=RAM[0x95];
- p=&device[latestListen&0x0f];
-
- if (b==0x3f)
- switch (latestSaListen&0xf0) {
- case 0xf0:
- if (p->isopen==0) {
- p->isopen=1;
- i=(*p->openf)((char *)serialBuffer, serialPtr, latestSaListen&0x0f);
- serialPtr=0;
- RAM[0x90]=i;
- if (i) {
- p->isopen=0;
- (*p->closef)(latestSaListen&0x0f); } }
- if (p->flushf) (*p->flushf)(latestSaListen&0x0f);
- break;
- case 0x60:
- if (p->isopen==0) {
- p->isopen=1;
- (*p->openf)(NULL, 0, latestSaListen&0x0f);
- for (i=0; i<serialPtr; i++)
- (*p->putf)(serialBuffer[i], latestSaListen&0x0f);
- serialPtr=0; }
- if (p->flushf) (*p->flushf)(latestSaListen&0x0f);
- break;
- case 0xe0:
- p->isopen=0;
- (*p->closef)(latestSaListen&0x0f);
- break;
- default:
- DebugStr("\pUnimplemented Serial Command"); break;
- }
-
- latestListen=trapListen;
- latestSaListen=b;
-
- i60(); /* RTS */
- }
-
- static void FloppyReadyTrap(void)
- {
- extern void i60(void);
-
- a = 0x01;
- flags &=(~NEG+ZER);
- i60(); /* RTS */
- }
-
-
-
- static byte SerialDummy(void) { return 2; }
-